package com.douqu.game.main.util;


import com.bean.core.util.TimeUtils;
import com.douqu.game.core.config.PlayerLvConfig;
import com.douqu.game.core.config.StableDataConfig;
import com.douqu.game.core.config.VipConfig;
import com.douqu.game.core.config.common.CommonData;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.database.model.PlayerModel;
import com.douqu.game.core.e.E_BattleDetailType;
import com.douqu.game.core.e.E_PlayerStatus;
import com.douqu.game.core.e.E_StableDataType;
import com.douqu.game.core.entity.ChangeGoods;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.activity.MatchBaseInfo;
import com.douqu.game.core.entity.battle.BattleInitParam;
import com.douqu.game.core.entity.battle.PlayerBattleData;
import com.douqu.game.core.entity.ext.SettingInfo;
import com.douqu.game.core.entity.ext.data.challenge.WorldMapTaskData;
import com.douqu.game.core.entity.world.map.CityBean;
import com.douqu.game.core.entity.world.map.SpriteBean;
import com.douqu.game.core.entity.world.map.SpritePlayerBean;
import com.douqu.game.core.entity.world.map.WorldMapData;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.factory.WordFactory;
import com.douqu.game.core.factory.WorldInfoFactory;
import com.douqu.game.core.netty.NettyConnection;
import com.douqu.game.core.protobuf.*;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;
import com.douqu.game.core.util.SendUtils;
import com.douqu.game.main.GameServer;
import com.douqu.game.main.msg.param.RequestParam;
import com.douqu.game.main.msg.param.StartBattleParam;
import com.douqu.game.main.server.RecordManager;
import com.douqu.game.main.server.ServerManager;
import com.douqu.game.main.server.WorldManager;
import com.douqu.game.main.server.entity.PlayerGoodsChange;
import com.douqu.game.main.server.entity.ServerInfoBattle;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by bean on 2016/12/1.
 */
public class MsgUtils {

    public static void sendChat(String nickName, String content, SGCommonProto.E_CHAT_TYPE chatType)
    {
        SGCommonProto.ChatItem.Builder chatItem = SGCommonProto.ChatItem.newBuilder();
        chatItem.setNickName(nickName);
        chatItem.setChatType(chatType);
        chatItem.setContent(content);
        chatItem.setSendTime(DataFactory.currentTime);
        GameServer.getInstance().getWorldManager().dispatchChat(chatItem.build());
    }

//    public static void sendHideFunction(PlayerController playerController) {
//        if (FunctionFactory.hideFunctionList.isEmpty())
//            return;
//
//        SGSystemProto.S2C_FunctionStatus.Builder response = SGSystemProto.S2C_FunctionStatus.newBuilder();
//        response.addAllHide(FunctionFactory.hideFunctionList);
//        playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_System_FunctionStatus_VALUE, response.build().toByteArray());
//    }

    public static void sendLoginFail(NettyConnection connection, int waitTime) {
        SGSystemProto.S2C_Login.Builder response = SGSystemProto.S2C_Login.newBuilder();
        response.setResult(SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_NEED_WAIT);
        response.setWaitTime(waitTime);
        connection.sendMsg(SGMainProto.E_MSG_ID.MsgID_System_Login_VALUE, response.build().toByteArray());
    }

    public static void sendLoginFailMergeServer(NettyConnection connection, List<PlayerModel> users) {
        SGSystemProto.S2C_Login.Builder response = SGSystemProto.S2C_Login.newBuilder();
        response.setResult(SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_CHOOSE_ROLO);
        for (PlayerModel model : users) {
            response.addMergeInfo(SGCommonProto.MergePlayerInfo.newBuilder().
                    setObjectIndex(model.getObjectIndex()).
                    setNickName(model.getName()).
                    setAvatar(model.getAvatar()).
                    setLv(model.getLevel()).
                    setVipLv(model.getVipLevel()).
                    setServerName(model.getServerName() == null ? "" : model.getServerName()).setFc(model.getFc()));
        }
        connection.sendMsg(SGMainProto.E_MSG_ID.MsgID_System_Login_VALUE, response.build().toByteArray());
    }


    public static void sendLoginFail(NettyConnection connection, SGCommonProto.E_CHANNEL_TYPE channel) {
        SGSystemProto.S2C_Login.Builder response = SGSystemProto.S2C_Login.newBuilder();
        response.setResult(SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_FAIL);
        response.setChannel(channel);
        connection.sendMsg(SGMainProto.E_MSG_ID.MsgID_System_Login_VALUE, response.build().toByteArray());
    }

    public static void sendLoginFail(NettyConnection connection, SGCommonProto.E_LOGIN_RESULT loginResult, SGCommonProto.E_CHANNEL_TYPE channelType, SGCommonProto.E_CAMP_TYPE campType) {
        SGSystemProto.S2C_Login.Builder response = SGSystemProto.S2C_Login.newBuilder();
        response.setResult(loginResult);
        response.setChannel(channelType);
        if (campType != null) {
            response.setRecommendCamp(campType);
        }
        connection.sendMsg(SGMainProto.E_MSG_ID.MsgID_System_Login_VALUE, response.build().toByteArray());
    }

    public static void sendLoginFail(NettyConnection connection) {
        SGSystemProto.S2C_Login.Builder response = SGSystemProto.S2C_Login.newBuilder();
        response.setResult(SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_FAIL);
        connection.sendMsg(SGMainProto.E_MSG_ID.MsgID_System_Login_VALUE, response.build().toByteArray());
    }

    public static void sendLoginFailForBattle(NettyConnection connection, SGCommonProto.E_CHANNEL_TYPE channelType, SGCommonProto.BattleData.Builder battleData) {
        SGSystemProto.S2C_Login.Builder response = SGSystemProto.S2C_Login.newBuilder();
        response.setResult(SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_BATTLE);
        response.setChannel(channelType);
        response.setBattleData(battleData);
        connection.sendMsg(SGMainProto.E_MSG_ID.MsgID_System_Login_VALUE, response.build().toByteArray());
    }


    public static void sendRequestBattle(PlayerController playerController, byte[] data)
    {
        playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Player_RequestBattle_VALUE, data);
    }


    /**
     * 跨服阵营战
     *
     * @param playerController
     * @param host
     * @param port
     * @param target
     * @param battleId
     */
    public static void sendSpanCampBattle(PlayerController playerController, String battleId, String host, int port, MatchBaseInfo target)
    {
        SGChallengeProto.S2C_RequestBattle.Builder response = SGChallengeProto.S2C_RequestBattle.newBuilder();

        SGCommonProto.PlayerBattleBaseInfo.Builder baseInfo = SGCommonProto.PlayerBattleBaseInfo.newBuilder();
        baseInfo.setPlayerIndex(target.getObjectIndex());
        baseInfo.setNickName(target.getName());
        baseInfo.setAvatar(target.getAvatar() == null ? "" : target.getAvatar());
        baseInfo.setLv(target.getLv());

        response.setTargetPlayer(baseInfo);

        response.setBattleId(battleId);
        response.setBattleType(SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_SPAN_CAMP);

        SGCommonProto.ServerInfo.Builder serverInfoData = SGCommonProto.ServerInfo.newBuilder();
        serverInfoData.setHost(host);
        serverInfoData.setPort(port);

        response.setServerInfo(serverInfoData);

        StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.CAMP_BATTLE_MAP.getCode());
        if(stableDataConfig == null)
            stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.ARENA_MAP.getCode());

        if(stableDataConfig != null)
            response.setMapId(stableDataConfig.intValue);

        LogUtils.info(playerController.getName() + ",connection:" + (playerController.getTcpConnection() != null) + "通知玩家阵营战的战斗服务器信息 -> " + response);

        sendRequestBattle(playerController, response.build().toByteArray());

        WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(playerController);
        if(worldMapData != null)
        {
            worldMapData.removeLookCity(playerController.getObjectIndex());
            SpritePlayerBean spritePlayerBean = worldMapData.getPlayerActionBean(playerController.getObjectIndex());
            if(spritePlayerBean != null)
                spritePlayerBean.setInCity(false);

            playerController.setInWorldMap(false);
        }
    }


    /**
     * @param playerController
     * @param battleType
     * @param battleDetailType
     * @param targetIndex      通知战斗服务器的参数
     * @param clientParams     通知客户端的参数
     * @Param initParam 通知战斗服务器的参数
     */
    public static boolean startBattle(PlayerController playerController, SGCommonProto.E_BATTLE_TYPE battleType,
                                      E_BattleDetailType battleDetailType, String targetIndex, BattleInitParam initParam, RequestParam... clientParams)
    {
        if (CoreUtils.isNullOrEmpty(targetIndex)) {
            LogUtils.info("传入数据异常");
            return false;
        }

        if (playerController.getStatus() == E_PlayerStatus.WAIT_BATTLE_CREATE) {
            LogUtils.info("已经请求过战斗,等待创建 -> " + playerController.getName());
            playerController.sendUnknown();
            return false;
        }
        ServerInfoBattle serverInfo = ServerManager.getInstance().getFreeBattleServer();
        if (serverInfo == null) {
            LogUtils.info("战斗服务器没有开启!");
            playerController.sendWarn(WordFactory.BATTLE_SERVER_ERROR);
            return false;
        }

        startBattle(serverInfo, playerController, battleType, battleDetailType, targetIndex, initParam, clientParams);
        return true;
    }

    public static String startBattle(ServerInfoBattle serverInfo, PlayerController playerController, SGCommonProto.E_BATTLE_TYPE battleType, E_BattleDetailType battleDetailType, String targetIndex, BattleInitParam initParam, RequestParam... clientParams)
    {
        String battleId = CoreUtils.createBattleId(playerController.getObjectIndex(), targetIndex);

        LogUtils.info("通知战斗服务器创建战斗 -> battleId:" + battleId + " type:" + battleType + " battleDetailType:" + battleDetailType + " target:" + targetIndex + " ip:" + serverInfo.getHost() + " port:" + serverInfo.getPort());
        PlayerBattleData battleData = new PlayerBattleData(battleId, battleDetailType, serverInfo.getHost(), serverInfo.getPort());
        playerController.setBattleData(battleData);
        playerController.setStatus(E_PlayerStatus.WAIT_BATTLE_CREATE);
        GameServer.getInstance().getWorldManager().addBattleCachePlayer(playerController);

        if (battleDetailType == E_BattleDetailType.PVP_WORLD_MAP) {
            PlayerController targetController = GameServer.getInstance().getWorldManager().getPlayerController(targetIndex);
            if (targetController != null) {
                battleData = new PlayerBattleData(battleId, battleDetailType, serverInfo.getHost(), serverInfo.getPort());
                targetController.setBattleData(battleData);
                targetController.setStatus(E_PlayerStatus.WAIT_BATTLE_CREATE);
                GameServer.getInstance().getWorldManager().addBattleCachePlayer(targetController);
            }
        }

        serverInfo.sendBattleInit(battleId, battleType.getNumber(), battleDetailType.getCode(), playerController.getObjectIndex(), targetIndex, initParam);

        StartBattleParam startBattleParam = new StartBattleParam(battleId, battleType, battleDetailType, serverInfo.getHost(), serverInfo.getPort(), playerController.getObjectIndex(), targetIndex, initParam, clientParams);

        serverInfo.addStartBattleParam(startBattleParam);

        if(battleType != SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_WORLD_MAP)
        {
            WorldMapData worldMapData = WorldInfoFactory.getInstance().getWorldMapData(playerController);
            if(worldMapData != null)
            {
                worldMapData.removeLookCity(playerController.getObjectIndex());
                SpritePlayerBean spritePlayerBean = worldMapData.getPlayerActionBean(playerController.getObjectIndex());
                if(spritePlayerBean != null)
                    spritePlayerBean.setInCity(false);

                playerController.setInWorldMap(false);
            }
        }

        LogUtils.debug("玩家请求开始战斗 -> battleType:" + battleType + " battleDetailType:" + battleDetailType + " ,等待战斗服务器返回......");

        return battleId;
    }

    public static String checkBattleCardCount(Player player) {
        PlayerLvConfig playerLvConfig = DataFactory.getInstance().getGameObject(DataFactory.PLAYER_LV_KEY, player.getLv());
        if (playerLvConfig != null) {
            VipConfig vipConfig = DataFactory.getInstance().getGameObject(DataFactory.VIP_KEY, player.getVipLevel());
            int maxCardCount = playerLvConfig.battleSoldierCount + (vipConfig == null ? 0 : vipConfig.additionalCard);
            int minCardCount = playerLvConfig.minBattleSoldierCount;
            if (player.getCardData().getBattleCardList().size() > maxCardCount)
                return WordFactory.getWord(WordFactory.CANNOT_BE_GREATER_THAN_THE_NUMBER_OF_CARRY, maxCardCount);
            if (player.getCardData().getBattleCardList().size() < minCardCount)
                return WordFactory.getWord(WordFactory.CANNOT_BE_LESS_THAN_THE_NUMBER_OF_CARRY, minCardCount);
        }
        return null;
    }


    public static void addPlayerGoodsChange(int code, PlayerController playerController) {
        ChangeGoods changeGoods = playerController.getPlayer().getChangeGoods();
        if (changeGoods != null) {
            List<SGCommonProto.FlushData> flushDataList = changeGoods.getChangeGoodsList();
            String currentTime = TimeUtils.getCurrentTime();
            for (SGCommonProto.FlushData flushData : flushDataList) {
                if (flushData.getType() == SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS
                        || flushData.getType() == SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_CARDS
                        || flushData.getType() == SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_PROPS
                        || flushData.getType() == SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_EQUIP) {
                    RecordManager.getInstance().addPlayerGoodsChange(new PlayerGoodsChange(currentTime,
                            playerController.getObjectIndex(), playerController.getPlayer().getNameLv(),
                            code, flushData.getType().getNumber(), flushData.getId(), flushData.getChange(), flushData.getCurValue()));
                }
            }
        }
    }

    /**
     * 发送战报
     */
    public static void sendMapBattleReport(CityBean cityBean, SpriteBean attacker, SpriteBean defender, String winnerIndex) {
        SGMapProto.S2C_MapBattleReport.Builder response = SGMapProto.S2C_MapBattleReport.newBuilder();
        SGCommonProto.MapBattleResult.Builder data = SGCommonProto.MapBattleResult.newBuilder();
        data.setWinnerIndex(winnerIndex);

        data.setAttacker(attacker.parseBaseInfo());
        data.setDefender(defender.parseBaseInfo());

        response.setResult(data);

        LogUtils.debug("battleReport -> " + response);

        byte[] byteArray = response.build().toByteArray();

        cityBean.dispatchMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_BattleReport_VALUE, byteArray, true);

        if (!attacker.isInCity()) {
            attacker.sendMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_BattleReport_VALUE, byteArray);
        }

        if (!defender.isInCity()) {
            defender.sendMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_BattleReport_VALUE, byteArray);
        }
    }




    public static void sendWorldMapTaskChange(PlayerController playerController, CommonData... commonDatas) {
        if (commonDatas.length == 0)
            return;


        //获取玩家的大地图 任务完成信息
        SGMapProto.S2C_MapTaskChange.Builder response = SGMapProto.S2C_MapTaskChange.newBuilder();
        WorldMapTaskData WorldMapTaskInfo = playerController.getPlayer().getWorldMapTaskData();
        Map<Integer, Integer> maps = new HashMap<>();
        Integer value;
        for (CommonData commonData : commonDatas) {
            if (commonData.value > 0) {
                value = maps.get(commonData.id);
                if (value != null) {
                    value += commonData.value;
                } else {
                    value = commonData.value;
                }
                maps.put(commonData.id, value);
            }
        }
        SGCommonProto.WorldMapTaskObject.Builder taskValue;
        for (Map.Entry<Integer, Integer> entry : maps.entrySet()) {
            taskValue = SGCommonProto.WorldMapTaskObject.newBuilder();
            taskValue.setType(SGCommonProto.E_WORLDMAPTASK_TYPE.forNumber(entry.getKey()));
            taskValue.setValue(WorldMapTaskInfo.getComplete(entry.getKey()));
            taskValue.setAddValue(entry.getValue());
            response.addTaskValue(taskValue);
        }
        response.setMilitaryExploitValue(WorldMapTaskInfo.getMilitaryExploitValue());
        response.setTodayExp(WorldMapTaskInfo.getTodayExp());
        //response.setRedPoint(WorldMapTaskInfo.checkRedPointRemindAllCondition());
        playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_WorldMap_TaskChange_VALUE, response.build().toByteArray());

        if (WorldMapTaskInfo.checkRedPointRemindAllCondition()) {
            SendUtils.sendRedPointRemind(playerController, SGCommonProto.E_RED_POINT_TYPE.RED_POINT_TYPE_WORLDMAP_TASK);
        }
    }



    public static void sendLogin(SGCommonProto.E_CHANNEL_TYPE channel, SGCommonProto.E_LOGIN_TYPE loginType, PlayerController playerController) {
        //返回登录初始化信息
        SGSystemProto.S2C_Login.Builder logResponse = SGSystemProto.S2C_Login.newBuilder();
        logResponse.setResult(SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_SUCCESS);
        SGCommonProto.PlayerBaseInfo userInfo = SGCommonProto.PlayerBaseInfo.newBuilder()
                .setPlayerIndex(playerController.getObjectIndex())
                .setNickName(playerController.getName())
                .setAvatar(playerController.getPlayer().avatar)
                .setLv(playerController.getPlayer().getLv())
                .setCamptypeValue(playerController.getPlayer().camp)
                .setMasterId(playerController.getPlayer().master)
                .build();
        logResponse.setPlayerInfo(userInfo);

//        logResponse.setChannel(channel);
        logResponse.setChannel(SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_QUICK);

        logResponse.setLoginType(loginType);

        SettingInfo settingInfo = playerController.getPlayer().getExtInfo(SettingInfo.class);
        SGCommonProto.AutoRecoverInfo.Builder autoRecoverBuilder = SGCommonProto.AutoRecoverInfo.newBuilder();
        autoRecoverBuilder.setEnable(settingInfo.getAutoRecover().enable);
        autoRecoverBuilder.setUseTimes(settingInfo.getAutoRecover().maxUseTimes);
        autoRecoverBuilder.setPercent(settingInfo.getAutoRecover().percent);
        logResponse.setAutoRecoverInfo(autoRecoverBuilder);

        LogUtils.info("返回给客户端登录成功的消息->", logResponse);
        playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_System_Login_VALUE, logResponse.build().toByteArray());
    }


    /**
     * 冲值验证结果
     * @param playerController
     * @param result
     * @param outTradeNo
     * @param rechargeType
     * @param content
     */
    public static void sendRechargeVerify(PlayerController playerController, boolean result, String outTradeNo, SGCommonProto.E_RECHARGE_TYPE rechargeType, String content)
    {
        SGPlayerProto.S2C_RechargeVerify.Builder response = SGPlayerProto.S2C_RechargeVerify.newBuilder();
        response.setResult(result);
        response.setOutTradeNo(outTradeNo);
        response.setRechargeType(rechargeType);
        response.setContent(content == null ? "" : content);
        playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_Bonus_RechargeVerify_VALUE, response.build().toByteArray());

        LogUtils.info("发送冲值验证 -> " + response);
    }



}
